#include "stdafx.h"
#include "XMenuButtonImpl.h"

#include <Util.h>
#include <UIUtil.h>
#include <DrawUtil.h>

//////////////////////////////////////////////////////////////////////////

template <class I>
CXMenuButtonImpl<I>::CXMenuButtonImpl()
{
    m_pMenuPre = NULL;
    m_nArrowWidth = 20;
}

template <class I>
CXMenuButtonImpl<I>::~CXMenuButtonImpl()
{
}

//////////////////////////////////////////////////////////////////////////
// IXMenuButton

template <class I>
BOOL CXMenuButtonImpl<I>::put_ArrowImage(IN LPCTSTR szXNC, IN int nSubImageCount, IN int nArrowWidth)
{
    XSAFE_RELEASE(m_pButtonDraw);
    {
        m_nArrowWidth = nArrowWidth;

        XSAFE_RELEASE(m_pButtonDraw);
        if(SUCCEEDED(Util::CreateObject(&m_pButtonDraw)))
        {
            m_pButtonDraw->put_ImagePath(szXNC);
            m_pButtonDraw->put_SubCount(nSubImageCount, 1);

            ImageDrawParams Params =
            {
                2, m_nArrowWidth, 2,
                2, m_nArrowWidth,
                2, m_nArrowWidth, 2,
            };
            m_pButtonDraw->put_DrawParams(&Params);
        }
        Invalidate();
    }
    return TRUE;
}

template <class I>
BOOL CXMenuButtonImpl<I>::put_Menu(IN IXMenuPre* pMenuPre, int nSubMenuIndex)
{
    ReleaseData();
    m_pMenuPre = pMenuPre->GetSubMenu(nSubMenuIndex);
    return (m_pMenuPre != NULL);
}

template <class I>
BOOL CXMenuButtonImpl<I>::put_MenuId(IN int nMenuId, int nSubMenuIndex)
{
    return put_MenuNameEx(MAKEINTRESOURCE(nMenuId), nSubMenuIndex, NULL);
}

template <class I>
BOOL CXMenuButtonImpl<I>::put_MenuName(IN LPCTSTR lpMenuName, int nSubMenuIndex)
{
    return put_MenuNameEx(lpMenuName, nSubMenuIndex, NULL);
}

template <class I>
BOOL CXMenuButtonImpl<I>::put_MenuIdEx(IN int nMenuId, int nSubMenuIndex, IN HINSTANCE hInstance)
{
    return put_MenuNameEx(MAKEINTRESOURCE(nMenuId), nSubMenuIndex, hInstance);
}

template <class I>
BOOL CXMenuButtonImpl<I>::put_MenuNameEx(IN LPCTSTR lpMenuName, int nSubMenuIndex, IN HINSTANCE hInstance)
{
    if(hInstance == NULL)
        hInstance = ::GetModuleHandle(NULL);

    ReleaseData();
    IXMenuPre* pMenuPre = NULL;
    if(SUCCEEDED(Util::CreateObject(&pMenuPre)))
    {
        if(pMenuPre->LoadMenu(lpMenuName, hInstance))
        {
            m_pMenuPre = pMenuPre->GetSubMenu(nSubMenuIndex);
        }
        pMenuPre->Release();
    }
    return (m_pMenuPre != NULL);
}

template <class I>
BOOL CXMenuButtonImpl<I>::get_Menu(OUT IXMenuPre** ppMenuPre)
{
    *ppMenuPre = m_pMenuPre;
    if((*ppMenuPre) != NULL)
    {
        (*ppMenuPre)->AddRef();
        return TRUE;
    }
    return FALSE;
}

//////////////////////////////////////////////////////////////////////////
// IXBaseObj
template <class I>
void CXMenuButtonImpl<I>::OnFinalRelease()
{
    superclass::OnFinalRelease();
    ReleaseData();
}

//////////////////////////////////////////////////////////////////////////
// CXMenuButtonImpl
template <class I>
void CXMenuButtonImpl<I>::ReleaseData()
{
    m_pMenuPre = NULL;
}

// CXFrameImpl
template <class I>
BOOL CXMenuButtonImpl<I>::OnClicked(const POINT* pt)
{
    RECT rcClient;
    get_WindowRect(&rcClient);

    if(rcClient.right - pt->x > m_nArrowWidth)
    {
        superclass::OnClicked(pt);
    }
    else if(m_pMenuPre != NULL)
    {
        {
            if(FAILED(InvokeEventHandler(this, MenuButtonEvent_InitMenuPre, (LPARAM)(IXMenuPre*)m_pMenuPre)))
                return FALSE;
        }

        get_ScreenRect(&rcClient);
        XWND xWnd = UIUtil::GetHolderWindow(dynamic_cast<IXControl*>(this));
        int nResult = m_pMenuPre->TrackPopupMenu(rcClient.left, rcClient.bottom + 1, xWnd);

        if(nResult > 0)
            InvokeEventHandler(this, MenuButtonEvent_Selected, (LPARAM)nResult);
    }
    return TRUE;
}

//////////////////////////////////////////////////////////////////////////
// IXFrame

template <class I>
void CXMenuButtonImpl<I>::GetAutoSize(OUT LPSIZE pAutoSize)
{
    if(m_pButtonDraw == NULL)
    {
        superclass::GetAutoSize(pAutoSize);
    }
    else
    {
        m_pButtonDraw->get_ImageSize(pAutoSize);
    }

    SIZE sizeText = {0};
    if(!m_strText.empty())
    {
        superclass::GetAutoSize(&sizeText);
        sizeText.cx += m_nArrowWidth + 4;
        sizeText.cy += 2;
    }

    pAutoSize->cx = max(pAutoSize->cx, sizeText.cx);
    pAutoSize->cy = max(pAutoSize->cy, sizeText.cy);
}

template <class I>
void CXMenuButtonImpl<I>::Draw(XCANVAS xCanvas, const RECT& rcDraw)
{
    superclass::Draw(xCanvas, rcDraw);

    RECT rcWnd;
    get_WindowRect(&rcWnd);

    HRESULT hResult = S_OK;
    if(m_pButtonDraw != NULL)
    {
        hResult = m_pButtonDraw->Draw(xCanvas, &rcWnd);
    }

    if(!m_strText.empty())
    {
        IXFont* pFont = NULL;
        IXTextEnv* pTextEnv = NULL;

        get_Font(&pFont);
        get_TextEnv(&pTextEnv);

        rcWnd.right -= m_nArrowWidth;

        if(TestControlFlags(ESkin_Down))
            ::OffsetRect(&rcWnd, 1, 1);

        DrawUtil::XDrawText(xCanvas, m_strText, m_strText.Length(), &rcWnd, pTextEnv, pFont);
    }
}